package com.wwj.my_ummary.config.antibrush;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

/**
 * 限制接口访问次数
 */
//@Aspect
//@Component
public class RequestLimitContract {

    private static final Logger logger = LoggerFactory.getLogger(RequestLimitContract.class);
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Value("${myPath}")
    private String path;

    private static String limitPath = "/safeLimit/limit";

    @Before("@annotation(limit)")
    public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {
        try {


            Object[] args = joinPoint.getArgs();
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = servletRequestAttributes.getResponse();
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof HttpServletRequest) {
                    request = (HttpServletRequest) args[i];
                    break;
                }
            }
            if (request == null) {
                throw new RequestLimitException("方法中缺失HttpServletRequest参数");
            }
            String ip = request.getRemoteAddr();
            String url = request.getRequestURL().toString();
            String key = "req_limit_".concat(url).concat(ip);
            if (!redisTemplate.hasKey(key) || StringUtils.isEmpty(redisTemplate.opsForValue().get(key))) {
                redisTemplate.opsForValue().set(key, String.valueOf(1), limit.time(), TimeUnit.MILLISECONDS);
            } else {
                Integer getValue = Integer.parseInt(redisTemplate.opsForValue().get(key)) + 1;
                redisTemplate.opsForValue().set(key, String.valueOf(getValue), limit.time(), TimeUnit.MILLISECONDS);
            }
            int count = Integer.parseInt(redisTemplate.opsForValue().get(key));
            if (count == 1) {
                //创建一个定时器
                TimerTask timerTask = new TimerTask() {
                    @Override
                    public void run() {
                        redisTemplate.delete(key);
                    }
                };
                //这个定时器设定在time规定的时间之后会执行上面的remove方法，也就是说在这个时间后它可以重新访问
                new Timer().schedule(timerTask, limit.time());
            }
            if (count > limit.count()) {
                long time = limit.time();
                double fen = time/1000/60;

                logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过[" + fen + "]分钟内限定的次数[" + limit.count() + "]");
                // throw new RequestLimitException();
                //端口号
                String toLomitPath = "http://" + request.getServerName() + ":" + request.getServerPort() +path+limitPath;
                logger.info(toLomitPath);
                assert response != null;
                response.sendRedirect(toLomitPath);
            }
        } catch (RequestLimitException e) {
            throw e;
        } catch (Exception e) {
            logger.error("发生异常", e);
        }
    }


}